package main

import (
	"bytes"
	"database/sql"
	"errors"
	"fmt"
	"io/ioutil"
	"strings"
)

// 获取地址私钥
func getPrivateKey(db *sql.DB, address string) (string, error) {
	stmt, err := db.Prepare("SELECT privateKey FROM keys WHERE address = ? LIMIT 1;")
	if err != nil {
		return "", err
	}
	defer stmt.Close()

	var privateKey string
	rows, err := stmt.Query(address)
	if err != nil {
		return "", err
	}

	if !rows.Next() {
		return "", errors.New("not found")
	}
	err = rows.Scan(&privateKey)
	return privateKey, err
}

// 扫描地址列表
func scanAddresses(db *sql.DB, offset, limit int) ([]string, error) {
	stmt, err := db.Prepare("SELECT address FROM keys ORDER BY id LIMIT ? OFFSET ?;")
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	rows, err := stmt.Query(limit, offset)
	if err != nil {
		return nil, err
	}

	addresses := make([]string, 0)
	for rows.Next() {
		var address string
		if err := rows.Scan(&address); err != nil {
			return nil, err
		}
		addresses = append(addresses, address)
	}
	return addresses, nil
}

// 扫描漂亮的地址
func scanBeautifulAddress(db *sql.DB, level int) ([]string, error) {
	offset := 0
	const limit = 100000
	beautifulAddresses := make([]string, 0)

	for {
		addresses, err := scanAddresses(db, offset, limit)
		if err != nil {
			return nil, err
		}

		for _, address := range addresses {
			if numberOfContinuousAlphas(address) >= level {
				beautifulAddresses = append(beautifulAddresses, address)
			}
		}

		if len(addresses) < limit {
			break
		}
		offset += limit
	}
	return beautifulAddresses, nil
}

// 导出所有地址
func exportAddresses(db *sql.DB, path string, limitPerBatch int) error {
	batch := 0
	offset := 0

	for {
		batch += 1
		addresses, err := scanAddresses(db, offset, limitPerBatch)
		if err != nil {
			return err
		}

		if len(addresses) == 0 {
			break
		}

		buf := bytes.NewBufferString(strings.Join(addresses, "\n"))
		filename := fmt.Sprintf("%s/addresses_%d.txt", path, batch)
		err = ioutil.WriteFile(filename, buf.Bytes(), 0600)
		if err != nil {
			return err
		}

		if len(addresses) < limitPerBatch {
			break
		}
		offset += limitPerBatch
	}

	return nil
}
